/* confest.h - confidence estimator interfaces */


#ifndef CONFEST_H
#define CONFEST_H

#define dassert(a) assert(a)

#include <stdio.h>

#include "host.h"
#include "misc.h"
#include "machine.h"
#include "stats.h"


/* an entry in a CT */
struct confest_ct_ent_t {
  md_addr_t mispred_dist;		/* distance from last misprediction */
  struct confest_ct_ent_t *prev, *next; /* lru chaining pointers */
};

/* correct/incorrect table(CT) def */
struct confest_ct_t {
    struct {
      int tsize;		/* CIR table size, number of confidence states */
      int bhrsize;		/* BHR table size, number of history regs */
      int *table;		/* CIR table(CT) */
      //int *shiftregs;		/* level-1 history table */
      int shift_width;		/* amount of history in level-1 shift regs */
      int xor;			/* history xor address flag */
    } config;
};

/* confidence estimator def */
struct confest_t {

  struct confest_ct_t *ct;

  /* stats */
  counter_t high_hits;		/* num correct high confidence predictions */
  counter_t low_hits;			/* num correct low confidence predictions */
  counter_t high_misses;		/* num incorrect high confidence predictions */
  counter_t low_misses;		/* num incorrect high confidence predictions */

  counter_t lookups;			/* num lookups */
};

/* confidence estimator update information */
struct confest_update_t {
  char *phigh;		/* high prediction counter */
  char *plow;		/* low prediction counter */
};

/* print estimator stats */
void
confest_stats(struct confest_t *estimator,	/* branch predictor instance */
	      FILE *stream);			/* output stream */

/* register confidence esitmator stats */
void
confest_reg_stats(struct confest_t *estimator,	/* branch predictor instance */
		struct stat_sdb_t *sdb);	/* stats database */

/* create a confidence estimator */
struct confest_t *			/* confidence estimator instance */
confest_create(unsigned int tsize,	/* CIR table size */
	       unsigned int bhrsize,	/* BHR table size */
	       unsigned int shift_width,/* history register width */
	       unsigned int xor);  	/* history xor address flag */


int						/* predicted branch confidence(HIGH/LOW) */
confest_lookup(struct confest_t *estimator,	/* confidence estimator instance */
	       md_addr_t baddr,			/* branch address */
	       int *shiftregs,		        /* level-1 history table */
	       enum md_opcode op);		/* opcode of instruction */



void
confest_update(struct confest_t *estimator,	/* confidence estimator instance */
	       md_addr_t baddr,			/* branch address */
	       int pred_conf,			/* predicted confidence (0-LOW/1-HIGH) */
	       int correct,			/* was earlier addr prediction ok? */
	       int *shiftregs,	        	/* level-1 history table */
	       enum md_opcode op);		/* opcode of instruction */


#ifdef foo0
/* OBSOLETE */
/* dump confidence estimator state (for debug) */
void
confest_dump(struct confest_t *estimator,	/* confidence estimator instance */
	   FILE *stream);			/* output stream */
#endif

#endif /* CONFEST_H */
